using UnityEngine;

namespace HyuFrameWork
{
    public class MonoSingletonHelper 
    {
        public const string RootGameObjectName = "/MonoSingletonRoot";

        public static GameObject GetRoot() 
        {
            var root = GameObject.Find(RootGameObjectName);
            if (root == null) {
                root = CreateRootGameObject();
            }

            return root;
        }
        static GameObject CreateRootGameObject () 
        {
            var go = new GameObject(RootGameObjectName);
            Object.DontDestroyOnLoad(go);
            return go;
        }
    }
    
    //可删除的MonoSingleton
    public abstract class MonoSingleton<T> : MonoBehaviour where T : MonoSingleton<T>
    {
        protected static bool _isDestroied;//永久删除
        protected static T m_instance;

        public static T Instance
        {
            get
            {
                if (!m_instance && !_isDestroied)//_isDestroied：防止永久删除后再次创建
                {
                    m_instance = FindObjectOfType<T>();
                    if (m_instance == null)
                    {
                        var go = new GameObject(typeof(T).Name);
                        m_instance = go.AddComponent<T>();
                        var parent = MonoSingletonHelper.GetRoot();
                        if (parent != null)
                        {
                            go.transform.SetParent(parent.transform);
                        }
                    }
                }

                return m_instance;
            }
        }

        public void Startup()
        {

        }

        protected virtual void Awake()
        {
            // 已经有实例存在了，删除新的
            if (m_instance != null && m_instance != this) 
            {
                var scriptName = name;
                var gameObjectName = gameObject.name;
                Debug.LogWarning("MonoSingleton is duplicated, " +
                                 $"gameobject name [{gameObjectName}],script name [{scriptName}]");
                enabled = false;
                gameObject.SetActive(false);
                Destroy(gameObject);
                return;
            }
            
            if (m_instance == null)
            {
                m_instance = this as T;
            }

            if(Application.isPlaying)
                DontDestroyOnLoad(gameObject);
            Init();
        }

        public virtual void Init()
        {

        }
        
        //若是只有自己一个则永久删除 不再在场景中出现
        //若是多建立的则会删除多余的 不会永久删除
        protected virtual void OnDestroy()
        {
            if (m_instance != null && m_instance == this) 
            {
                m_instance = null;
                _isDestroied = true;   
            }
        }
    }
}